<template>
  <div
    class="orderNumber"
    @mousedown="mousedown"
    :style="{
      left: position.left + '%',
      top: position.top + '%',
      width: position.width ? position.width : '30px',
      height: position.height ? position.height : '30px',
    }"
  >
    <div
      v-for="item in dotList"
      :key="item.side"
      :class="[item.side, 'pointDot']"
      :style="getDotStyle(item)"
      :data-side="item.side"
    ></div>
  </div>
</template>

<script>
export default {
  props: {
    position: {
      type: Object,
      default: () => {
        return {
          left: 0,
          top: 0,
        };
      },
    },
  },
  data() {
    return {
      dotList: [
        { side: "top", cursor: "n-resize" },
        { side: "bottom", cursor: "n-resize" },
        { side: "left", cursor: "e-resize" },
        { side: "right", cursor: "e-resize" },
        { side: "top-left", cursor: "se-resize" },
        { side: "top-right", cursor: "sw-resize" },
        { side: "bottom-left", cursor: "sw-resize" },
        { side: "bottom-right", cursor: "se-resize" },
      ],
    };
  },
  mounted() {
    console.log(this.position);
  },
  methods: {
    getDotStyle(item) {
      const [side, position] = item.side.split("-");
      const style = { [side]: "0%", cursor: item.cursor };
      if (!position) {
        const side2 = ["top", "bottom"].includes(side) ? "left" : "top";
        style[side2] = "50%";
      } else {
        style[position] = "0%";
      }
      return style;
    },
    mousedown(e) {
      e.stopPropagation();
      if (e.target.className.indexOf("pointDot") != -1) {
        this.changeZoom(
          e,
          e.target.getAttribute("data-side"),
          e.target.parentNode
        );
      } else {
        this.onMove(e);
      }
    },
    changeZoom(e, dataSide, parDom) {
      e.stopPropagation();
      e.preventDefault();
      let imageContain = this.$parent.$refs.temp;
      let transform = imageContain.style.transform;
      //处理方法缩小
      let scale = 1;
      if (transform.indexOf("scale") != -1) {
        let match = transform.match(/scale\(([^)]+)\)/);
        if (match) {
          scale = parseFloat(match[1].split(",")[0]);
        }
      }
      // 获取鼠标按下的坐标
      const downX = e.clientX;
      const downY = e.clientY;
      const elRect = parDom.getBoundingClientRect();
      const onMousemove = (_e) => {
        // 移动的x距离
        const disX = _e.clientX - downX;
        // 移动的y距离
        const disY = _e.clientY - downY;

        const [side, position] = dataSide.split("-");

        // 是否是上方缩放圆点
        const hasT = side === "top";
        // 是否是左方缩放圆点
        const hasL = [side, position].includes("left");

        let width = (elRect.width + (hasL ? -disX : disX)) / scale;
        let height = (elRect.height + (hasT ? -disY : disY)) / scale;

        // 如果是左侧缩放圆点，修改left位置
        let left = (elRect.left + (hasL ? disX : 0)) / scale;

        // 如果是上方缩放圆点，修改top位置
        let top = (elRect.top + (hasT ? disY : 0)) / scale;

        if (!position) {
          // 如果是四个正方位
          if (["top", "bottom"].includes(side)) {
            // 上下就不改变宽度
            width = elRect.width / scale;
          } else {
            // 左右就不改变高度
            height = elRect.height / scale;
          }
        }
        // 处理逆向缩放
        if (width < 0) {
          width = -width;
          left -= width;
        }
        if (height < 0) {
          height = -height;
          top -= height;
        }
        let mask = this.$parent.$el.querySelector(".pardom");
        let maskRect = mask.getBoundingClientRect();
        let maskLeft = maskRect.left / scale;
        let maskTop = maskRect.top / scale;
        let maskWidth = maskRect.width / scale;
        let maskHeight = maskRect.height / scale;
        parDom.setStyle({
          left: ((left - maskLeft) * 100) / maskWidth + "%",
          top: ((top - maskTop) * 100) / maskHeight + "%",
          width: width + "px",
          height: height + "px",
        });
      };
      const onMouseup = (_e) => {
        window.removeEventListener("mousemove", onMousemove);
        window.removeEventListener("mouseup", onMouseup);
      };
      window.addEventListener("mousemove", onMousemove);
      window.addEventListener("mouseup", onMouseup);
    },
    onMove(e) {
      let imageContain = this.$parent.$refs.temp;
      let transform = imageContain.style.transform;
      //处理方法缩小
      let scale = 1;
      if (transform.indexOf("scale") != -1) {
        let match = transform.match(/scale\(([^)]+)\)/);
        if (match) {
          scale = parseFloat(match[1].split(",")[0]);
        }
      }
      const el = e.target;
      // 记录按下的位置
      const downX = e.clientX;
      const downY = e.clientY;
      let left = parseFloat(e.target.style.left);
      let top = parseFloat(e.target.style.top);
      const onMousemove = (e) => {
        // 当前鼠标的位置减去鼠标在盒子里的位置就是要移动的距离
        let moveX = (e.clientX - downX) / scale;
        let moveY = (e.clientY - downY) / scale;
        el.setStyle({
          left: left + (moveX * 100) / e.target.parentNode.clientWidth + "%",
          top: top + (moveY * 100) / e.target.parentNode.clientHeight + "%",
        });
      };

      const onMouseup = (_e) => {
        // 移除document事件
        window.removeEventListener("mousemove", onMousemove);
        window.removeEventListener("mouseup", onMouseup);
      };
      // 位window注册鼠标移动事件
      window.addEventListener("mousemove", onMousemove);
      // 鼠标抬起事件
      window.addEventListener("mouseup", onMouseup);
    },
  },
};
</script>

<style lang="less" scoped>
.orderNumber {
  position: absolute;
  cursor: move;
  z-index: 9999999999;
  background-color: rgba(0, 0, 0, 0.1);
}
/deep/ .pointDot {
  position: absolute;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background-color: #3a7afe;
  transform: translate(-50%, -50%);
  cursor: se-resize;
  &[data-side*="right"] {
    transform: translate(50%, -50%);
  }
  &[data-side*="bottom"] {
    transform: translate(-50%, 50%);
  }
  &[data-side="bottom-right"] {
    transform: translate(50%, 50%);
  }
}
/deep/ .newTextInput {
  background-color: red;
  width: 200px;
  height: 100px;
  display: flex;
  justify-content: space-between;
  padding: 20px;
  box-sizing: border-box;
}
/deep/ .inputText {
  outline: none;
  display: block;
  width: 50%;
  height: 20px;
}
</style>
